use contract::{OderSide, OrderType, OrderUpdateRequest};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug,Clone)]
pub struct OrderUpdateDO {
    pub action: String,
    pub order_id: String,
    pub user_id: i64,
    pub side: String,
    pub order_type: String,
    pub base_asset: String,
    pub quote_asset: String,
    pub price: f64,
    pub quantity: f64,
    pub original_quantity: f64,
    pub order_time: i64,
    pub version: i32,
    pub via: String,
    pub symbol: String,
    // execType:String,
    pub pass_time_seconds: i64, //取消订单超时时间.如果订单已经超时,则取消该订单.只有在取消订单中生效.
    pub is_batch_order_end: bool,
}

impl OrderUpdateDO {
    pub fn new_from(request: OrderUpdateRequest) -> Self {
        OrderUpdateDO {
            action: request.action,
            order_id: request.order_id,
            user_id: request.user_id,
            side: request.side,
            order_type: request.order_type,
            base_asset: request.base_asset,
            quote_asset: request.quote_asset,
            price: request.price,
            quantity: request.quantity,
            original_quantity: request.original_quantity,
            order_time: request.order_time,
            version: request.version,
            via: request.via,
            symbol: request.symbol,
            pass_time_seconds: request.pass_time_seconds,
            is_batch_order_end: request.is_batch_order_end,
        }
    }

    pub fn get_symbol(&self) -> Option<String> {
        let symbol = &self.symbol;
        if symbol == "" {
            if &self.base_asset == "" || &self.quote_asset == "" {
                None
            } else {
                let mut result = "".to_string();
                result.push_str(&self.base_asset);
                result.push_str("_");
                result.push_str(&self.quote_asset);
                Some(result)
            }
        } else {
            Some(symbol.to_string())
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_getsymbol_from_symbol() {
        let n = OrderUpdateDO{
            action:"place".to_string(),
            order_id:"123456".to_string(),
            user_id:10000,
            side:"buy".to_string(),
            order_type:"limit".to_string(),
            base_asset:"BTC".to_string(),
            quote_asset:"USDT".to_string(),
            price:10000.0,
            quantity:2.0,
            original_quantity:2.0,
            order_time: 546544221544,
            version: 0,
            via: "".to_string(),
            symbol: "BTC_USDT1".to_string(),
            pass_time_seconds: -1,
            is_batch_order_end: false,
        };
        println!("{:?}",n);
        assert_eq!(n.get_symbol().unwrap_or_else(||"".to_string()),"BTC_USDT1");
        // println!("get symbol is :{:?}",);
    }

    #[test]
    fn test_getsymbol_from_baseassert() {
        let n = OrderUpdateDO{
            action:"place".to_string(),
            order_id:"123456".to_string(),
            user_id:10000,
            side:"buy".to_string(),
            order_type:"limit".to_string(),
            base_asset:"BTC1".to_string(),
            quote_asset:"USDT".to_string(),
            price:10000.0,
            quantity:2.0,
            original_quantity:2.0,
            order_time: 546544221544,
            version: 0,
            via: "".to_string(),
            symbol: "".to_string(),
            pass_time_seconds: -1,
            is_batch_order_end: false,
        };
        println!("{:?}",n);
        assert_eq!(n.get_symbol().unwrap_or_else(||"".to_string()),"BTC1_USDT");
        // println!("get symbol is :{:?}",);
    }
}
